#include "EntityManager.h"
#include "Entity.h"
#include "System.h"
#include "Logger.h"

namespace BPL
{

EntityManager::EntityManager()
{
    Entity::entityManager = this;
    System::entityManager = this;

    mpt_grid = new EntityGrid(20,20);
    mpt_map = new EntityMap(200,200);

	sizeTile = 30;
}

EntityManager::~EntityManager()
{
    delete mpt_grid;
    delete mpt_map;
}

EntityId EntityManager::getNextAvailableID()
{
    static unsigned int counter = 0;
	counter +=1;
    return counter;
}

void EntityManager::registerEntity(Entity* ent)
{
    mpt_entities.insert(std::pair<EntityId,EntityPtr>(ent->getID(), EntityPtr(ent)));
}

void EntityManager::registerEntity(EntityPtr ent)
{
    mpt_entities.insert(std::pair<EntityId,EntityPtr>(ent->getID(), ent));
}

EntityPtr EntityManager::registerNextEntity()
{
	EntityPtr e(new Entity(getNextAvailableID()));
	registerEntity(e);

	return e;
}

EntityPtr EntityManager::registerNextStaticEntity(const sf::Vector2i& position)
{
	EntityPtr e(new Entity(getNextAvailableID()));
	registerStaticEntity(e, position);

	return e;
}
EntityPtr EntityManager::registerNextDynamicEntity(const sf::Vector2f& position, int type)
{
	EntityPtr e(new Entity(getNextAvailableID()));
	registerDynamicEntity(e, position, type);

	return e;
}

void EntityManager::registerStaticEntity(EntityPtr ent, const sf::Vector2i& position)
{
    registerEntity(ent);
    mpt_map->addEntity(ent->getID(), position);
}

void EntityManager::registerDynamicEntity(EntityPtr ent, const sf::Vector2f& position, int type)
{
    registerEntity(ent);
    mpt_grid->addEntity(type, ent->getID(), position);
}

EntityPtr EntityManager::getEntity(EntityId ent)
{
    Assert(mpt_entities.find(ent) != mpt_entities.end());
	return mpt_entities[ent];
}

EntityId EntityManager::getStaticEntityIn(const sf::Vector2i position)
{
	return mpt_map->getEntity(position);
}

bool EntityManager::hasEntity(EntityId ent)
{
	return mpt_entities.find(ent) != mpt_entities.end();
}

void EntityManager::killEntity(EntityId id)
{
    std::map<EntityId, EntityPtr>::iterator toKill = mpt_entities.find(id);
	if(toKill != mpt_entities.end())
	{
		mpt_entities.erase(toKill);
		mpt_grid->deleteEntity(0,id);
		mpt_map->deleteEntity(id);

		std::map<FamilyId, std::map<EntityId, boost::shared_ptr<Component> > >::iterator itr;
		for(itr = mpt_componentStore.begin(); itr != mpt_componentStore.end(); itr++)
		{
			std::map<EntityId, boost::shared_ptr<Component> >::iterator toKill2 = itr->second.find(id);
			if(toKill2 != itr->second.end())
				itr->second.erase(toKill2);
		}	
	}
}

std::map<EntityId, EntityPtr> EntityManager::getAllEntities() const
{
    return mpt_entities;
}

EntityGrid* EntityManager::getGrid() const
{
	return mpt_grid;
}
EntityMap* EntityManager::getMap() const
{
	return mpt_map;
}


}
